﻿using MyCompany.MyProject.Model.Models;
using MyCompany.MyProject.Model.Models.Tenants;
using SqlSugar;
using System.Reflection;

namespace MyCompany.MyProject.Common.DB
{
    public static class TenantUtil
    {
        /// <summary>
        /// 获取多租户实体
        /// </summary>
        /// <param name="tenantType"></param>
        /// <returns></returns>
        public static List<Type> GetTenantEntityTypes(TenantTypeEnum? tenantType = null)
        {
            return RepositorySetting.Entitys
                .Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass)
                .Where(s => IsTenantEntity(s, tenantType))
                .ToList();
        }

        /// <summary>
        /// 判断是否是租户实体
        /// </summary>
        /// <param name="type"></param>
        /// <param name="tenantType"></param>
        /// <returns></returns>
        public static bool IsTenantEntity(this Type type, TenantTypeEnum? tenantType = null)
        {
            var mta = type.GetCustomAttribute<MultiTenantAttribute>();
            if (mta is null) return false;
            if (tenantType != null)
            {
                if (mta.TenantType != tenantType) return false;
            }
            return true;
        }
        /// <summary>
        /// 动态获取多租户表名称
        /// </summary>
        /// <param name="type"></param>
        /// <param name="db"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static string GetTenantTableName(this Type type, ISqlSugarClient db, string id)
        {
            var entityInfo = db.EntityMaintenance.GetEntityInfo(type);
            return $@"{entityInfo.DbTableName}_{id}";
        }

        public static string GetTenantTableName(this Type type, ISqlSugarClient db, SysTenant tenant)
        {
            return GetTenantTableName(type, db, tenant.Id.ToString());
        }

        /// <summary>
        /// 设置多租户表
        /// </summary>
        /// <param name="db"></param>
        /// <param name="id"></param>
        public static void SetTenantTable(this ISqlSugarClient db, string id)
        {
            var types = GetTenantEntityTypes(TenantTypeEnum.Tables);
            foreach (var type in types)
            {
                db.MappingTables.Add(type.Name, type.GetTenantTableName(db, id));
            }
        }

        /// <summary>
        /// 获取分库多租户数据库链接字符串
        /// </summary>
        /// <param name="tenant"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public static ConnectionConfig GetConnectionConfig(this SysTenant tenant)
        {
            if (tenant == null) throw new ArgumentException("Tenant DbType Must");

            return new ConnectionConfig()
            {
                ConfigId = tenant.ConfigId,
                DbType = tenant.DbType!.Value,
                ConnectionString = tenant.Connection,
                IsAutoCloseConnection = true,
                MoreSettings = new ConnMoreSettings()
                {
                    IsAutoRemoveDataCache = true,
                    SqlServerCodeFirstNvarchar = true,
                }
            };
        }
    }
}
